package com.atguigu.gmall.rabbitmq.service;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.rabbitmq.pojo.GmallCorrelationData;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.UUID;

/**
 * @Auther 赵乾坤
 * @Date 2021-01-09 18:06
 *  提供 MQ发消息    普通  延迟消息
 */
@Component
@SuppressWarnings("all")
public class RabbitService {
    @Autowired
    private RabbitTemplate rabbitTemplate; //信道   回调机制  交换机应答 队列应答
    @Autowired
    private RedisTemplate redisTemplate;
    //发普通消息
    public void sendMessage(String exchange,String routingKey,Object message){

        //子对象  消息丢失 回调下面这个对象进行重新发送
        GmallCorrelationData gmallCorrelationData = new GmallCorrelationData();
        //ID  UUID
        String uuid = UUID.randomUUID().toString();
        gmallCorrelationData.setId(uuid);
        //交换机
        gmallCorrelationData.setExchange(exchange);
        gmallCorrelationData.setRoutingKey(routingKey);
        gmallCorrelationData.setMessage(message);

        //在此将发送  Redis中
        // Map  rabbit:message = new HashMap();
        //rabbit:message.put(k,v)
        redisTemplate.opsForHash().put(
                "rabbit:message",uuid, JSONObject.toJSONString(gmallCorrelationData));
        //发消息
        rabbitTemplate.convertAndSend(
                exchange,routingKey,
                message,gmallCorrelationData);
    }

    //    //发延迟消息 （基于死信的）
    public void sendDeadLetterMessage(String exchange, String routingKey, Object msg,
                                      int delayTime) {//delayTime  延迟多久
        //子对象  消息丢失 回调下面这个对象进行重新发送
        GmallCorrelationData gmallCorrelationData = new GmallCorrelationData();
        //ID  UUID
        String uuid = UUID.randomUUID().toString();
        gmallCorrelationData.setId(uuid);
        //交换机
        gmallCorrelationData.setExchange(exchange);
        gmallCorrelationData.setRoutingKey(routingKey);
        gmallCorrelationData.setMessage(msg);
        //是否是延迟消息
        gmallCorrelationData.setDelay(true);
        //延迟时间
        gmallCorrelationData.setDelayTime(delayTime);

        redisTemplate.opsForHash().put(
                "rabbit:message",uuid, JSONObject.toJSONString(gmallCorrelationData));
        //发延迟消息
        rabbitTemplate.convertAndSend(
                exchange,routingKey,
                msg,
                message -> {
                    //延迟时间
                    // setExpiration : 死信过期转发       单位是毫秒    2*60*60
                    message.getMessageProperties().
                            setExpiration(String.valueOf(delayTime*1000));
                    System.out.println("发送时间：" + new Date());
                    return message;
                },
                gmallCorrelationData);
    }


    //    //发延迟消息 （基于死信的）
    public void sendDelayMessage(String exchange, String routingKey, Object msg,
                                      int delayTime) {//delayTime  延迟多久
        //子对象  消息丢失 回调下面这个对象进行重新发送
        GmallCorrelationData gmallCorrelationData = new GmallCorrelationData();
        //ID  UUID
        String uuid = UUID.randomUUID().toString();
        gmallCorrelationData.setId(uuid);
        //交换机
        gmallCorrelationData.setExchange(exchange);
        gmallCorrelationData.setRoutingKey(routingKey);
        gmallCorrelationData.setMessage(msg);
        //是否是延迟消息
        gmallCorrelationData.setDelay(true);
        //延迟时间
        gmallCorrelationData.setDelayTime(delayTime);

        redisTemplate.opsForHash().put(
                "rabbit:message",uuid, JSONObject.toJSONString(gmallCorrelationData));
        //发延迟消息
        rabbitTemplate.convertAndSend(
                exchange,routingKey,
                msg,
                message -> {
                    //延迟时间
                    // setDelay：延迟插件   单位是毫秒  //局部设置
                    message.getMessageProperties().
                            setDelay(delayTime*1000);
                    System.out.println("发送时间：" + new Date());
                    return message;
                },
                gmallCorrelationData);
    }
    }

